<!-- 导入组件 -->
<template>
  <el-dialog
    :title="title"
    :visible.sync="visible"
    width="555px"
    append-to-body
    @open="importConfigOpen"
    :before-close="handleClose"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
  >
    <avue-form ref="importConfigForm" v-model="importForm" :option="importConfig.option">
      <template slot="imgUrl">
        <el-upload
          ref="excelFile"
          class="importConfigDialog"
          drag
          action="#"
          :accept="accept"
          limit="1"
          :auto-upload="false"
          :before-remove="handleBeforeRemove"
          :on-change="changeFile"
        >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
          <div class="el-upload__tip" slot="tip">
            <div>请上传{{ accept }}标准格式文件</div>
          </div>
        </el-upload>
      </template>
      <template slot="excelTemplate">
        <el-button type="primary" @click="handleDownLoad()" icon="el-icon-download el-icon--right"> 模板下载 </el-button>
      </template>
    </avue-form>
    <div slot="footer" class="dialog-footer">
      <el-button v-preventReClick type="primary" size="small" :loading="btnLoading" @click="saveImport" icon="el-icon-circle-plus-outline">保 存 </el-button>
      <el-button @click="cancelImport" size="small" icon="el-icon-circle-close">取 消</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { getToken } from '@/util/auth';
import request from '@/router/axios';
import { exprot, getExprot } from '@/api/repair/failureconfig';
const xlsx = require('xlsx');
export default {
  name: 'frontEndImport',
  inject: ['globalStartLoad', 'globalEndLoad'],
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    url: {
      type: String,
      default: ''
    },
    exportName: {
      type: String,
      default: ''
    },
    accept: {
      type: String,
      default: '.xls,.xlsx'
    },
    mapfields: {
      type: Object,
      default: () => ({})
    },
    title: {
      type: String,
      default: '导入'
    },
    anotherExportMethod: {
      type: Boolean,
      default: false
    },
    exportCode: {
      type: String,
      dafault: ''
    }
  },
  data() {
    return {
      localData: [],
      importForm: {
        imgUrl: {}
      },
      btnLoading: false,
      importConfig: {
        fileLoading: false,
        fileLoadingText: '文件下载中，请稍后...',
        option: {
          emptyBtn: false,
          submitBtn: false,
          column: [
            {
              label: '附件上传',
              prop: 'imgUrl',
              type: 'upload',
              loadText: '文件上传中，请稍等',
              span: 24,
              propsHttp: {
                res: 'data'
              },
              data: {},
              headers: {
                'Blade-Auth': getToken()
              },
              tip: '只能上传拓展名为.xls,.xlsx的文件',
              action: '#'
            },
            {
              label: '模板下载',
              prop: 'excelTemplate',
              formslot: true,
              span: 24
            }
          ]
        }
      }
    };
  },
  methods: {
    importConfigOpen() {
      for (const key in this.importForm) {
        this.importForm.imgUrl = {};
      }
      this.$nextTick(() => {
        this.$refs.excelFile.clearFiles();
      });
    },
    handleClose() {
      this.setVisible(false);
    },
    async handleBeforeRemove(file, fileList) {
      let res = await this.$confirm(`确定移除 ${file.name}？`, {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      });
      if (res) {
        this.importForm.imgUrl = {};
        this.$message({
          type: 'success',
          message: '移除成功!'
        });
      }
    },
    async changeFile(val) {
      let nameArray = val.name.split('.');
      if (nameArray[nameArray.length - 1] === 'xlsx' || nameArray[nameArray.length - 1] === 'xls') {
        // file保存选择的文件
        this.importForm.imgUrl = val.raw;
        // 读取文件不是立马能够读取到的，所以是异步的，使用Promise
        try {
          this.btnLoading = true;
          let dataBinary = await new Promise((resolve) => {
            // Web API构造函数FileReader，可实例化对象，去调用其身上方法，去读取解析文件信息
            let reader = new FileReader();
            // console.log("实例化对象有各种方法", reader);
            reader.readAsBinaryString(val.raw); // 读取raw的File文件
            reader.onload = (ev) => {
              // console.log("文件解析流程进度事件", ev);
              resolve(ev.target.result); // 将解析好的结果扔出去，以供使用
            };
          });

          /**
           * 2. 使用xlsx插件去解析已经读取好的二进制excel流文件
           * */
          let workBook = xlsx.read(dataBinary, { type: 'binary', cellDates: true });
          // excel中有很多的sheet，这里取了第一个sheet：workBook.SheetNames[0]
          let firstWorkSheet = workBook.Sheets[workBook.SheetNames[0]];
          // 分为第一行的数据，和第一行下方的数据
          const header = this.getHeaderRow(firstWorkSheet);
          const data = xlsx.utils.sheet_to_json(firstWorkSheet);

          const tableData = data.map((item) => {
            const obj = {};
            for (const key in item) {
              if (key === '生产日期') {
                console.log(this.$moment(item[key]).format('yyyy-MM-DD hh:mm:ss'));
                obj[this.mapfields[key]] = this.$moment(item[key]).format('yyyy-MM-DD hh:mm:ss');
              } else {
                obj[this.mapfields[key]] = item[key];
              }
            }
            return obj;
          });
          this.localData = tableData;
        } catch (e) {
          this.$message({
            message: '文件格内容错误,请确认检查文件内容并重新上传',
            type: 'error',
            duration: 2000
          });
        } finally {
          this.btnLoading = false;
        }
      } else {
        this.$message({
          message: '文件格式错误,请确认文件内容并重新上传',
          type: 'warning',
          duration: 2000
        });
      }
    },
    getHeaderRow(sheet) {
      const headers = []; // 定义数组，用于存放解析好的数据
      const range = xlsx.utils.decode_range(sheet['!ref']); // 读取sheet的单元格数据
      let C;
      const R = range.s.r;
      /* start in the first row */
      for (C = range.s.c; C <= range.e.c; ++C) {
        /* walk every column in the range */
        const cell = sheet[xlsx.utils.encode_cell({ c: C, r: R })];
        /* find the cell in the first row */
        let hdr = 'UNKNOWN ' + C; // <-- replace with your desired default
        if (cell && cell.t) hdr = xlsx.utils.format_cell(cell);
        headers.push(hdr);
      }
      return headers; // 经过上方一波操作遍历，得到最终的第一行头数据
    },
    cancelImport() {
      this.setVisible(false);
    },
    setVisible(val) {
      this.$emit('update:visible', val);
    },
    saveImport() {
      this.$emit('save', this.localData);
      this.setVisible(false);
    },
    async handleDownLoad() {
      let res;
      try {
        if (this.anotherExportMethod) {
          const code = this.exportCode;
          res = await getExprot(code);
        } else {
          const data = {
            originalName: this.exportName,
            attachType: 'EXCEL'
          };
          res = await exprot({ data });
        }
      } catch (e) {
        const failMsg = await this.blobToJson(e.data);
        this.$message.error(failMsg.msg);
      }
      const blob = new Blob([res.data]);
      const fileName = this.exportName;
      const link = document.createElement('a');
      link.download = fileName;
      link.style.display = 'none';
      link.href = URL.createObjectURL(blob);
      document.body.append(link);
      link.click();
      URL.revokeObjectURL(link.href);
      document.body.removeChild(link);
    },
    async blobToJson(blob) {
      return new Promise((resolve, reject) => {
        blob.arrayBuffer().then(
          async (arrayBuffer) => {
            resolve(JSON.parse(Buffer.from(arrayBuffer).toString('utf-8')));
          },
          (error) => {
            reject(error);
          }
        );
      });
    }
  }
};
</script>

<style scoped lang="scss">
.importConfigDialog .el-upload {
  width: 100%;
}

.importConfigDialog .el-upload-dragger {
  width: 100%;
}

.custom-upload {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.model-download {
  cursor: pointer;

  .icon-color {
    color: #409eff;
    margin-right: 4px;
    font-size: 16px;
  }

  :hover {
    color: #409eff;
  }
}
</style>
